﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Administration;

namespace MsExchangeBcsConnector.ExchangeBdcModel.Helpers
{
    public class LoggingService : SPDiagnosticsServiceBase
    {
        private static object lockObject = new object();

        public static string DiagnosticAreaName = "MsEws Search Indexing Connector";
        private static LoggingService _instance;

        public static LoggingService Instance
        {
            get
            {
                if (_instance != null)
                {
                    return _instance;
                }

                lock (lockObject)
                {
                    if (_instance == null)
                    {
                        _instance = new LoggingService();
                    }
                }

                return _instance;
            }
        }

        private LoggingService()
            : base("MsEws Search Indexing Connector Logging Service", SPFarm.Local)
        {
        }

        protected override IEnumerable<SPDiagnosticsArea> ProvideAreas()
        {
            List<SPDiagnosticsArea> areas = new List<SPDiagnosticsArea>
            {
                new SPDiagnosticsArea(DiagnosticAreaName, new List<SPDiagnosticsCategory>
                {
                    new SPDiagnosticsCategory("MsEws_Verbose", TraceSeverity.Verbose, EventSeverity.Verbose),
                    new SPDiagnosticsCategory("MsEws_Info", TraceSeverity.Medium, EventSeverity.Information),
                    new SPDiagnosticsCategory("MsEws_Warning", TraceSeverity.High, EventSeverity.Warning),
                    new SPDiagnosticsCategory("MsEws_Error", TraceSeverity.Unexpected, EventSeverity.Error),
                    new SPDiagnosticsCategory("MsEws_Critical", TraceSeverity.Unexpected, EventSeverity.ErrorCritical)
                })
            };

            return areas;
        }

        public static void LogVerbose(string format, params object[] args)
        {
            LogVerbose(String.Format(format, args));
        }

        public static void LogVerbose(string message)
        {
            SPDiagnosticsCategory category = LoggingService.Instance.Areas[DiagnosticAreaName].Categories["MsEws_Verbose"];
            LoggingService.Instance.WriteTrace(0, category, TraceSeverity.Verbose, message);
        }

        public static void LogInfo(string format, params object[] args)
        {
            LogInfo(String.Format(format, args));
        }

        public static void LogInfo(string message)
        {
            SPDiagnosticsCategory category = LoggingService.Instance.Areas[DiagnosticAreaName].Categories["MsEws_Info"];
            LoggingService.Instance.WriteTrace(0, category, TraceSeverity.Medium, message);
        }

        public static void LogWarning(string format, params object[] args)
        {
            LogWarning(String.Format(format, args));
        }

        public static void LogWarning(string message)
        {
            SPDiagnosticsCategory category = LoggingService.Instance.Areas[DiagnosticAreaName].Categories["MsEws_Warning"];
            LoggingService.Instance.WriteTrace(0, category, TraceSeverity.High, message);
        }

        public static void LogError(string format, params object[] args)
        {
            LogError(String.Format(format, args));
        }

        public static void LogError(string message)
        {
            SPDiagnosticsCategory category = LoggingService.Instance.Areas[DiagnosticAreaName].Categories["MsEws_Error"];
            LoggingService.Instance.WriteTrace(0, category, TraceSeverity.Unexpected, message);
        }

        public static void LogError(Exception ex)
        {
            SPDiagnosticsCategory category = LoggingService.Instance.Areas[DiagnosticAreaName].Categories["MsEws_Error"];

            StringBuilder messageBuilder = new StringBuilder();
            messageBuilder.AppendFormat("Exeption: {0}. Message: {1}, StackTrace: {2}. ", ex.GetType().ToString(), ex.Message, ex.StackTrace);

            Exception inner = ex.InnerException;
            while (inner != null)
            {
                messageBuilder.AppendFormat("Inner exeption: {0}. Message: {1}. ", ex.GetType().ToString(), ex.Message);
                inner = inner.InnerException;
            }

            LoggingService.Instance.WriteTrace(0, category, TraceSeverity.Unexpected, messageBuilder.ToString());
        }

        public static void LogCritical(string format, params object[] args)
        {
            LogCritical(String.Format(format, args));
        }

        public static void LogCritical(string message)
        {
            SPDiagnosticsCategory category = LoggingService.Instance.Areas[DiagnosticAreaName].Categories["MsEws_Critical"];
            LoggingService.Instance.WriteTrace(0, category, TraceSeverity.Unexpected, message);
        }
    }
}
